package com.ve.compiler;

import android.content.Context;
import android.content.res.AssetManager;
import android.support.annotation.NonNull;
import android.util.Log;

import com.jaredrummler.android.shell.CommandResult;
import com.jaredrummler.android.shell.Shell;
import com.ve.utils.FileUtils;

import java.io.File;
import java.io.IOException;


public class Installer {
    private static final String TAG = Installer.class.getSimpleName();
    private static final String FILE_DATA = "data.zip";
    private static final String INSTALLED_FLAG = "installed.flag";

    private Shell.Console console;
    private String installPath;
    private ProgressListener progressListener;
    private AssetManager assetManager;


    public Installer(Context context) {
        this.installPath = (context.getFilesDir().getAbsolutePath());
        assetManager = context.getAssets();
    }

    public void setProgressListener(ProgressListener progressListener) {
        this.progressListener = progressListener;
    }

    public Shell.Console getConsole() {
        return console;
    }

    public boolean setup() {
        if (isInstalled()) {
            return true;
        }

        new Thread(() -> {
            try {
                message("解压");
                FileUtils.unZip(assetManager, FILE_DATA, installPath, false);

                console = new Shell.Console.Builder()
                        .useSH()
                        .setWatchdogTimeout(30000)
                        .build();

                message("安装编译环境");
                shell("cd " + installPath);
                shell("chmod +x busybox proot install/bin/*");
                String busybox = getBusybox();

                if (!new File(installPath, "rootfs").exists()) {
                    shell(busybox +" tar -xf rootfs.tar.gz >/dev/null");
                }
                message("安装编译器");
                if (!new File(installPath, "rootfs/sdcc").exists()) {
                    shell(busybox +" tar -xf sdcc.bz2 -C rootfs");
                }
                message("安装其他工具");
                shell(busybox +" cp ./install/bin/* ./rootfs/bin");

                message("清理缓存");
                shell(busybox +" rm install sdcc.bz2 rootfs.tar.gz -r");
                makeInstalledFlag();
                result(null);
            } catch (Exception e) {
                e.printStackTrace();
                result(e);
            }

        }).start();

        return false;

    }

    @NonNull
    private String getBusybox() {
        if (testBusybox("./busybox tar")) {
            return "./busybox";
        }
        return " ";
    }

    private void result(Exception e) {
        if (progressListener == null) {
            return;
        }
        if (e == null) {
            progressListener.onSucceed("安装成功");
        } else {
            progressListener.onFail(e.toString(), e);
        }
    }

    private void message(String text) {
        if (progressListener != null) {
            progressListener.onProgress(text);
        }
    }


    private void shell(String cmd) {

        CommandResult result = console.run(cmd);
        Log.d(TAG, "shell: "+cmd);
        if (result.isSuccessful()) {
            Log.d(TAG, String.format("out: [%d]%s",result.exitCode, result.getStdout()));
        } else {
            String stderr = result.getStderr();
            Log.d(TAG, String.format("err: [%d]%s",result.exitCode, stderr));
        }
    }
    private boolean testBusybox(String cmd) {

        CommandResult result = console.run(cmd);
        Log.d(TAG, "testBusybox: "+cmd);
        if (result.isSuccessful()) {
            //result.getStdout()
            Log.d(TAG, String.format("testBusybox.out: [%d]%s",result.exitCode, ""));
        } else {
            String stderr = result.getStderr();
            Log.d(TAG, String.format("testBusybox.err: [%d]%s",result.exitCode, ""));
        }
        return result.exitCode==1;
    }


    public boolean isInstalled() {
        return new File(installPath, INSTALLED_FLAG).exists();
    }

    private void makeInstalledFlag() {
        try {
            new File(installPath, INSTALLED_FLAG).createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
